package com.lemon.smartsafety.http.callback;

import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.lemon.smartsafety.BuildConfig;
import com.lemon.smartsafety.app.AppService;
import com.lemon.smartsafety.app.Constants;
import com.lemon.smartsafety.app.RefreshType;
import com.lemon.smartsafety.entity.base.ErrorResponse;
import com.lemon.smartsafety.entity.base.HandlerResult;
import com.lemon.smartsafety.entity.event.http.HttpCallbackEvent;
import com.lemon.smartsafety.utils.common.LoggerHelper;
import com.lemon.smartsafety.utils.common.StringUtils;
import com.zhy.http.okhttp.callback.StringCallback;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.util.Collection;

import okhttp3.Call;
import okhttp3.Request;

/**
 * Created by Cooliean on 16/1/20.
 */
public abstract class HandlerCallback<T> extends StringCallback {
    private static final String TAG = "HandlerCallback";
    private LoggerHelper loggerHelper = new LoggerHelper(HandlerCallback.class);
    private String mTag;
    /**
     * 附件数据
     */
    private Object other;


    private InnerCallBack<T> mInnerCallBack;


    public enum HttpFlow {
        START, PROGRESS, FINISH;
    }



    public HandlerCallback(String tag) {
        this.mTag = tag;
        this.setOther(RefreshType.REFRESH);
    }

    //    SUCCESS,ERROR,START,FINISH,PROGRESS;
    private HttpCallbackEvent<T> callbackEvent = new HttpCallbackEvent<>();
    @Override
    public synchronized void onBefore(Request request) {
        super.onBefore(request);

        Log.e("返回onBefore   "+mTag,new Gson().toJson(callbackEvent.getObj()));
        callbackEvent.setTag(this.mTag);
        callbackEvent.setHttpFlow(HttpFlow.START);
        AppService.getBus().post(callbackEvent);
    }



    @Override
    public synchronized void inProgress(float progress) {
        super.inProgress(progress);
        callbackEvent.setHttpFlow(HttpFlow.PROGRESS);
        callbackEvent.setProgress(progress);
        AppService.getBus().post(callbackEvent);
    }

    @Override
    public synchronized void onError(Call call, Exception e) {
        if (BuildConfig.DEBUG) {
            e.printStackTrace();
        }
        if (e instanceof SocketTimeoutException) {
            e = new Exception("请求超时");
        }
        if(e == null){
            e = new NullPointerException("取消请求");
        }
        if(e instanceof ConnectException){
            e = new Exception("网络异常，请检查网络。");
        }

        String msg = e.getLocalizedMessage();
        msg = StringUtils.nullValue(msg);
        if ("Canceled".equalsIgnoreCase(msg)) {
            msg = "取消请求";
        }
        Log.e(TAG, "error msg = " + msg);

        callbackEvent.setEventResult(Constants.Result.ERROR);
        callbackEvent.setMsg(msg);
    }

    @Override
    public synchronized void onResponse(String response) {

        Log.e("返回onResponse   "+mTag,response.trim());

        Gson gson = AppService.getGson();
        HandlerResult handlerResult = null;
        try {
            handlerResult = AppService.getGson().fromJson(response, HandlerResult.class);
        } catch (Exception e) {
            if (BuildConfig.DEBUG) {
                e.printStackTrace();
            }
        }
//        if (BuildConfig.DEBUG) {
//            loggerHelper.i(response);
//        }
        if (handlerResult == null) {
            handlerResult = new HandlerResult();
            handlerResult.setError(true);
            ErrorResponse errorResponse = new ErrorResponse(-1, "出错了");
            handlerResult.setError(errorResponse);
        }
        if (handlerResult.isError()) {
            callbackEvent.setEventResult(Constants.Result.ERROR);
            callbackEvent.setMsg(handlerResult.getError().getMsg());
            callbackEvent.setCode(handlerResult.getError().getCode());
            //AppService.getBus().post(callbackEvent);
        }else{
            try {
                //Log.e("yxy", "handlerResult.getError() = " + handlerResult.getError());
                //Log.e("yxy", "handlerResult.isError() = " + handlerResult.isError());
                //Log.e("yxy", "handlerResult.getResult() = " + handlerResult.getResult());
                T result = gson.fromJson(gson.toJson(handlerResult.getResult()), getType());
                callbackEvent.setEventResult(Constants.Result.SUCCESS);
                callbackEvent.setMsg(handlerResult.getError().getMsg());
                callbackEvent.setCode(handlerResult.getError().getCode());
                callbackEvent.setObj(result);
                if (mInnerCallBack != null) {
                    mInnerCallBack.onInnerCallBack(result);
                }
            } catch (Exception e) {
                e.printStackTrace();
                callbackEvent.setEventResult(Constants.Result.ERROR);
                if(e instanceof JsonSyntaxException){
                    callbackEvent.setMsg("JSON 格式不正确");
                }else{
                    callbackEvent.setMsg("内部转换出错");
                }
            }
        }
    }
    @Override
    public synchronized void onAfter() {
        super.onAfter();
        callbackEvent.setTag(this.mTag);
        callbackEvent.setHttpFlow(HttpFlow.FINISH);
        AppService.getBus().post(callbackEvent);
    }

    public void localCallBack(Collection<?> data){
        callbackEvent.setTag(this.mTag);
        callbackEvent.setHttpFlow(HttpFlow.FINISH);

        callbackEvent.setObj((T) data);
        if (data.isEmpty()) {
            callbackEvent.setEventResult(Constants.Result.ERROR);
            callbackEvent.setMsg("没有相关数据");
        }else{
            callbackEvent.setEventResult(Constants.Result.SUCCESS);
            callbackEvent.setMsg("操作成功");
        }
        AppService.getBus().post(callbackEvent);
    }

    public void sendCall(Collection<?> data) {
        HttpCallbackEvent callbackEvent = new HttpCallbackEvent<>();
        callbackEvent.setObj(data);
        callbackEvent.setHttpFlow(HttpFlow.FINISH);
        callbackEvent.setTag(this.mTag);
        if (data == null) {
            callbackEvent.setEventResult(Constants.Result.ERROR);
            callbackEvent.setMsg("操作失败");
        }else{
            callbackEvent.setEventResult(Constants.Result.SUCCESS);
            callbackEvent.setMsg("操作成功");
        }
        AppService.getBus().post(callbackEvent);
    }


    /**
     * 目前主要是用来做本地数据查询返回使用
     * @param <T>
     */
    public interface InnerCallBack<T>{
        public void onInnerCallBack(T data);
    }


    public Object getOther() {
        return other;
    }

    public void setOther(Object other) {
        if (other != null) {
            callbackEvent.setOther(other);
        }
        this.other = other;
    }


    public String getTag() {
        return mTag;
    }

    public InnerCallBack<T> getInnerCallBack() {
        return mInnerCallBack;
    }

    public void setInnerCallBack(InnerCallBack<T> innerCallBack) {
        mInnerCallBack = innerCallBack;
    }
}
